/*
 * openTCS copyright information:
 * Copyright (c) 2005-2011 ifak e.V.
 * Copyright (c) 2012 Fraunhofer IML
 *
 * This program is free software and subject to the MIT license. (For details,
 * see the licensing information (LICENSE.txt) you should have received with
 * this copy of the software.)
 */
package org.opentcs.guing.transport;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import static java.util.Objects.requireNonNull;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.opentcs.guing.components.dialogs.DialogContent;
import org.opentcs.guing.components.dialogs.InputValidationListener;
import org.opentcs.guing.model.ModelComponent;
import org.opentcs.guing.model.elements.PointModel;

/**
 * Eine Benutzerschnittstelle zum Auswählen einer Station oder eines
 * Meldepunktes als direktes Fahrtziel für ein Fahrzeug.
 *
 * @author Sebastian Naumann (ifak e.V. Magdeburg)
 */
public class PointPanel
    extends DialogContent {

  /**
   * Die zur Auswahl stehenden Stationen.
   */
  protected List<PointModel> fItems;
  /**
   * List of Listeners to be notified about the validity of user input.
   */
  private final List<InputValidationListener> validationListeners = new LinkedList<>();

  /**
   * Creates new form PointPanel
   *
   * @param items possible destination points
   */
  public PointPanel(List<PointModel> items) {
    initComponents();
    fItems = items;

    Collections.sort(fItems, getComparator());
    List<String> names = new ArrayList<>();

    for (PointModel pointModel : fItems) {
      names.add(pointModel.getName());
    }

    itemsComboBox.setModel(new DefaultComboBoxModel<>(new Vector<>(names)));
    JTextField textField = (JTextField) (itemsComboBox.getEditor().getEditorComponent());
    textField.getDocument().addDocumentListener(new DocumentListener() {
      @Override
      public void insertUpdate(DocumentEvent e) {
        verify();
      }

      @Override
      public void removeUpdate(DocumentEvent e) {
        verify();

      }

      @Override
      public void changedUpdate(DocumentEvent e) {
        verify();

      }

    });
  }

  public void addInputValidationListener(InputValidationListener listener) {
    requireNonNull(listener, "listener");

    this.validationListeners.add(listener);
    verify();
  }

  /**
   * Liefert einen Comparator zum Sortieren der Elemente.
   *
   * @return den Comparator
   */
  /**
   * Liefert das ausgewählte Ziel, zu dem das Fahrzeug hinbeordert werden soll.
   *
   * @return das Ziel oder
   * <code>null</code>, falls kein Ziel ausgewählt wurde
   */
  public ModelComponent getSelectedItem() {
    int index = itemsComboBox.getSelectedIndex();

    if (index == -1) {
      return null;
    }
    return fItems.get(index);
  }

  @Override
  public void update() {
    // wird nicht benötigt
  }

  @Override
  public void initFields() {
    // wird nicht benötigt
  }

  protected final Comparator<ModelComponent> getComparator() {
    return new Comparator<ModelComponent>() {

      @Override
      public int compare(ModelComponent item1, ModelComponent item2) {
        String s1 = item1.getName();
        String s2 = item2.getName();
        s1 = s1.toLowerCase();
        s2 = s2.toLowerCase();

        return s1.compareTo(s2);
      }
    };
  }

  private void verify() {
    JTextField textField = (JTextField) (itemsComboBox.getEditor().getEditorComponent());
    String inputText = textField.getText();
    for (PointModel pointModel : fItems) {
      if (pointModel.getName().equals(inputText)) {
        inputValidationSuccessful(true);
        return;
      }
    }
    inputValidationSuccessful(false);
  }

  private void inputValidationSuccessful(boolean success) {
    for (InputValidationListener valListener : validationListeners) {
      valListener.inputValidationSuccessful(success);
    }
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    itemsLabel = new javax.swing.JLabel();
    itemsComboBox = new javax.swing.JComboBox<>();

    setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 10, 5));

    itemsLabel.setFont(itemsLabel.getFont());
    java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("i18n/org/opentcs/plantoverview/dialogs/vehiclePopup"); // NOI18N
    itemsLabel.setText(bundle.getString("pointPanel.label_points.text")); // NOI18N
    add(itemsLabel);

    itemsComboBox.setEditable(true);
    itemsComboBox.setFont(itemsComboBox.getFont());
    add(itemsComboBox);
  }// </editor-fold>//GEN-END:initComponents

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JComboBox<String> itemsComboBox;
  private javax.swing.JLabel itemsLabel;
  // End of variables declaration//GEN-END:variables
}
